import './Workflow.scss';
import * as React from 'react';
import { connect } from 'react-redux';
import classnames from 'classnames';
import { doCreateNode } from '../../reducer/controller';
import { ICreateNodeData, ICreateNodeParam } from '../../reducer/const';
import { parseEventTarget, inValidDragNodeRange, getValidNodeRange } from '../../util/eventUtil';
import { Point } from '../../reducer/const';

export interface IWorkflowFlaotNodeProps {
    createNodeData: ICreateNodeData; // 执行新增节点数据
    doCreateNode: (param: ICreateNodeParam) => any; // 执行新增节点
}

class WorkflowFlaotNode extends React.Component<IWorkflowFlaotNodeProps, any> {
    private height: number = 40;
    private width: number = 140;
    constructor(props: IWorkflowFlaotNodeProps) {
        super(props);
        this.state = Object.assign({}, props.createNodeData);
    }
    componentWillReceiveProps(nextProps: IWorkflowFlaotNodeProps, nextContext: any) {
        if (nextProps.createNodeData.doIt) {
            this.hideFloatNode();
            this.props.doCreateNode(nextProps.createNodeData);
        } else {
            this.setState(Object.assign({}, nextProps.createNodeData));
        }
    }

    handleMouseMove = (e) => {
        if (this.dragAble()) {
            const nativeEvent = parseEventTarget(e);
            this.setState({
                x: nativeEvent.pageX,
                y: nativeEvent.pageY
            });
        }
    }

    handleMouseUp = () => {
        const {x, y, type, name, icon} = this.state;
        const point: Point = new Point(x, y);
        this.hideFloatNode();
        if (inValidDragNodeRange(point)) {
            const createNodeData: ICreateNodeData = {
                type: type,
                name: name,
                icon: icon,
                x: x,
                y: y
            };
            this.props.doCreateNode(createNodeData);
        }
    }


    hideFloatNode = () => {
        this.setState({
            type: -1
        });
    }

    dragAble = () => {
        return this.state.type !== undefined && this.state.type >= 0;
    }

    render() {
        const {name, icon, x = -1000, y = -1000} = this.state;
        const style = {
            display: this.dragAble() ? 'block' : 'none',
            width: this.width,
            height: this.height,
            top: (y - this.height / 2),
            left: Math.max(0, x - this.width / 2)
        };
        return (
            <div className='workflow__floatNode workflow__drag noselect' style={style} onMouseMove={this.handleMouseMove} onTouchMove={this.handleMouseMove} onMouseUp={this.handleMouseUp} onTouchEnd={this.handleMouseUp}>
                <div className='workflow__floatNode__icon' title={name} >
                    <span className={classnames('iconfont', icon)}></span>
                </div>
                <div className='workflow__floatNode__text'>{name} </div>
            </div>
        );
    }
};

const mapStateToProps = (state: any) => {
    const {createNodeData} = state.action;
    return { createNodeData };
};

const mapDispatchToProps = (dispatch: any) => ({
    doCreateNode: (createNodeData: ICreateNodeData) => dispatch(doCreateNode(createNodeData)),
});

export default connect(mapStateToProps, mapDispatchToProps)(WorkflowFlaotNode);
